﻿using System;
using System.Linq.Expressions;
using System.ServiceModel.Channels;
using System.Xml;
using ProLinq.Wcf.Linq.Expressions.Serialization;

namespace ProLinq.Wcf.Description
{
	internal class ExpressionMessageHeader : MessageHeader
	{
		private const String HeaderName = "expression";
		private const String HeaderNamespace = "http://prolinq/wcf";

		private readonly IExpressionSerializer _serializer;

		public ExpressionMessageHeader(Expression expression, IExpressionSerializer serializer)
		{
			this.Expression = expression;
			this._serializer = serializer;
		}

		public Expression Expression { get; private set; }

		public override string Name
		{
			get { return HeaderName; }
		}

		public override string Namespace
		{
			get { return HeaderNamespace; }
		}

		protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
		{
			var bytes = this._serializer.Serialize(this.Expression);
			writer.WriteBase64(bytes, 0, bytes.Length);
		}

		public static ExpressionMessageHeader Load(MessageHeaders headers, IExpressionSerializer serializer)
		{
			var index = headers.FindHeader(HeaderName, HeaderNamespace);
			if (index < 0)
				return null;

			var reader = headers.GetReaderAtHeader(index);
			var expressionBytes = reader.ReadElementContentAsBase64();
			var expression = serializer.Deserialize(expressionBytes);

			return new ExpressionMessageHeader(expression, serializer);
		}
	}
}